/* Discordia compiler */

%{
#include <math.h>
#include <sys/types.h>
#include <limits.h>
#include <db.h>

//#define DEBUG

char* vars[256][2];
char* temp;
%}

ID	"-"[^"\n"]+
QUOTE	"\""[^"\""]*"\""
NUMID	[A-Z][A-Za-z0-9]*"!"

%%

"KNOW YE THIS O MAN OF FAITH!\n"{QUOTE}"\n"	{
	//free(temp);
	temp=(char*)malloc(strlen(yytext));
	snprintf(temp, strlen(yytext), "%s", yytext);
	printf("%s", temp);
	free(temp);
	}

"KNOW THEE THIS O MAN OF FAITH!\n"{ID}"\n"|"KNOW THEE THIS O MAN OF FAITH!\n"{NUMID}"\n"	{
	char* temp2;
	char* tempid;
	int pos2=0;
	int pos=strlen("KNOW THEE THIS O MAN OF FAITH!\n")-1;
	printf("KNOW THEE THIS O MAN OF FAITH!\n");
	/*int pos2=(int)strstr((char*)(((int)yytext)+pos), "\"");
	//if (pos2!=NULL) {
	//pos2-=((int)yytext)+pos;
	//} else {
	//	pos2=0;
	//}
	//free(temp);
	//temp=malloc(pos);
	//snprintf(temp, pos, "%s", yytext);*/
	/*while(pos<strlen(yytext) && pos2!=-1) {*/
	/*	if (strstr((char*)(((int)yytext)+pos), "-") > strstr((char*)(((int)yytext)+pos), "\"") && strstr((char*)(((int)yytext)+pos), "\"") < strstr((char*)(((int)yytext)+pos), "!") && strstr((char*)(((int)yytext)+pos), "\"")!=NULL) {
			pos2=(int)strstr((char*)(((int)yytext)+pos), "\"");
			if (pos2==NULL) {
				pos2=-1;
			} else {
				pos2-=((int)yytext)+pos;
				temp2=malloc(pos2);
				snprintf(temp2, pos2, "%s%s", temp, (char*)(((int)yytext)+pos));
				//free(temp);
				//temp=temp2;
				//temp2=NULL;
				printf("%s", temp2);
				free(temp2);
				pos+=pos2;
			}
		} else {
	*/		if (yytext[pos+1]=='-') {
				/*pos2=pos+1;
				if (pos2==NULL) {
				#ifdef DEBUG
					printf("ID not found!\n");
				#endif
					pos2=-1;
				} else {*/
					/*pos2-=((int)yytext)+pos;*/
					pos++;
					pos2=(int)strstr(&yytext[pos], "\n");
					pos2-=(int)&yytext[pos];
					pos2;
					/*if (pos2==NULL) {
						pos2=-1;
					} else {
						pos2-=((int)yytext)+pos;
					}*/
				/*}*/
				#ifdef DEBUG
					printf("ID!\npos2: %i\npos: %i\n", pos2, pos);
				#endif
			} else {
				pos++;
				pos2=(int)strstr(&yytext[pos], "!");
				if (pos2==NULL) {
					pos2=-1;
				#ifdef DEBUG
					printf("NUMID not found!\n");
				#endif
				} else {
					/*pos2-=((int)yytext)+pos;*/
					pos2+=2;
					pos2-=(int)&yytext[pos];
				#ifdef DEBUG
					printf("pos2: %i\npos: %i\n", pos2, pos);
				#endif
				}
			}
			if (pos2!=-1) {
				tempid=malloc(pos2+1);
				snprintf(tempid, pos2+1, "%s", &yytext[pos]);
				int i=0;
				while (i<256 && vars[i][0]!=NULL && strcmp(vars[i][0], tempid)) {
					i++;
				}
				if (i<256) {
					temp2=malloc(strlen(vars[i][1]));
					sprintf(temp2, "%s", vars[i][1]);
					//free(temp);
					//temp=temp2;
					//temp2=NULL;
					printf("%s\n", temp2);
					free(temp2);
				}
			}
		/*}
	}
	printf("KNOW THEE THIS O MAN OF FAITH!\n");
	printf("%s\n", temp);*/
	free(tempid);
	}


{QUOTE}"\n"	{
	free(temp);
	temp=(char*)malloc(strlen(yytext)+1);
	snprintf(temp, strlen(yytext)+1, "%s", yytext);
	}

"\t"{ID}"\n"	{
	#ifdef DEBUG
	printf("%s\n\n", temp);
	#endif
	int pos=(int)strstr(yytext, "-")-(int)yytext;
	char* tempid=malloc(strlen(yytext)-pos);
	snprintf(tempid, strlen(yytext)-pos, "%s", (char*)(((int)yytext)+pos));
	int i=0;
	while (i<256 && vars[i][0]!=NULL && strcmp(vars[i][0], tempid)!=0) {
		i++;
	}
	if (i>=256) {
		printf("REMEMBER: KING KONG DIED FOR YOUR SINS!\nIn memory of RAW\n");
		return 0;
	}
	if (vars[i][0]==NULL) {
		vars[i][0]=malloc(strlen(yytext));
		snprintf(vars[i][0], strlen(yytext), "%s", tempid);
	} else {
		free(vars[i][1]);
	}
	vars[i][1]=malloc(strlen(temp));
	snprintf(vars[i][1], strlen(temp), "%s", temp);
	free(tempid);
	#ifdef DEBUG
	printf("%s\n", vars[i][1]);
	printf("%s\n", vars[i][0]);
	#endif
	}

[A-Z][A-Za-z0-9]*"!\n"	{
	char* tempid=malloc(strlen(yytext)+1);
	snprintf(tempid, strlen(yytext)+1, "%s", yytext);
	int i=0;
	while (i<256 && vars[i][0]!=NULL && strcmp(vars[i][0], tempid)!=0) {
		i++;
	}
	if (i>=256) {
		printf("REMEMBER: SAINT GULIK DIED FOR YOUR SINS!\nIn memory of RAW\n");
		return 0;
	}
	if (vars[i][0]==NULL) {
		vars[i][0]=malloc(strlen(yytext)+1);
		snprintf(vars[i][0], strlen(yytext)+1, "%s", tempid);
	} else {
		free(vars[i][1]);
	}
	vars[i][1]=malloc(2);
	snprintf(vars[i][1], 2, "5");
	free(tempid);
	}

[A-Z][A-Za-z0-9]*"! "("Hail "*)("Eris "*)"!\n"	{
	int pos=(int)strstr(yytext, "!")-(int)yytext;
	#ifdef DEBUG
	printf("pos: %i\nEWIGE BLUMENKRAFT!\n", pos);
	#endif
	int pos2=23;
	char* tempid=malloc(pos+3);
	snprintf(tempid, pos+1, "%s", yytext);
	tempid[pos]='!';
	tempid[pos+1]='\n';
	tempid[pos+2]='\0';
	#ifdef DEBUG
	printf("%s\n", tempid);
	#endif
	int hailcount=0;
	int eriscount=0;
	pos=pos+2;
	while (pos<strlen(yytext) && pos2!=NULL) {
		pos2=(int)strstr(&yytext[pos], "Hail ");
		if(pos2!=NULL){
			hailcount++;
			#ifdef DEBUG
			printf("pos: %i\n", pos);
			#endif
			pos=pos+5;
			#ifdef DEBUG
			printf("pos: %i\n", pos);
			#endif
		} else {
			pos2=(int)strstr(&yytext[pos], "Eris ");
			if (pos2!=NULL) {
				eriscount++;
				pos+=5;
			}
		}
	}
	int i=0;
	while ((i<256) && (vars[i][0]!=NULL) && (strcmp(vars[i][0], tempid) != 0)) {
		i++;
	}
	if (i>=256) {
		printf("REMEMBER: SAINT QUIXOTE DIED FOR YOUR SINS!\nIn memory of RAW\n");
		return 0;
	}
	if (vars[i][0]==NULL) {
		#ifdef DEBUG
		printf("THE ID IS NIL! RUN!\n");
		printf("Or is it... Name: %s\nIndice: %i\n", vars[i][0], i);
		#endif
		vars[i][0]=malloc(strlen(tempid)+1);
		snprintf(vars[i][0], strlen(tempid)+1, "%s", tempid);
		vars[i][1]=malloc(2);
		snprintf(vars[i][1], 2, "5");
		#ifdef DEBUG
		printf("The name: %s\nThe value: %s\n", vars[i][0], vars[i][1]);
		printf("Is it equal?: %i\n", strcmp(vars[i][0], tempid));
		#endif
	}
	#ifdef DEBUG
		printf("%s\n", vars[i][1]);
		printf("hails: %i\nerises: %i\n", hailcount, eriscount);
	#endif
	int num=atoi(vars[i][1]);
	#ifdef DEBUG
	printf("numeric number: %i\n", num);
	#endif
	num+=hailcount;
	num*=eriscount;
	#ifdef DEBUG
	printf("mutily modded numbriness: %i\n", num);
	#endif
	free(vars[i][1]);
	vars[i][1]=malloc(13);
	snprintf(vars[i][1], 13, "%i", num);
	free(tempid);
	#ifdef DEBUG
	printf("now the official: %s\n", vars[i][1]);
	#endif
	i=0;
	}

[A-Z][A-Za-z0-9]*"! "("Hail "*)("Discord "*)"!\n"	{
	int pos=strstr(yytext, "!")-(int)yytext;
	char* tempid=malloc(pos+3);
	snprintf(tempid, pos+1, "%s", yytext);
	tempid[pos]='!';
	tempid[pos+1]='\n';
	tempid[pos+2]='\0';
	int hailcount=0;
	int discount=0;
	pos+=2;
	int pos2=23;
	while (pos<strlen(yytext) && pos2!=NULL) {
		pos2=(int)strstr(&yytext[pos], "Hail ");
		if (pos2!=NULL) {
			hailcount++;
			pos=pos+5;
		} else {
			pos2=(int)strstr(&yytext[pos], "Discord ");
			if (pos2!=NULL) {
				discount++;
				pos=pos+8;
			}
		}
	}
	#ifdef DEBUG
	printf("hails: %i\ndiscords: %i\n", hailcount, discount);
	#endif
	int i=0;
	while ((i<256) && (vars[i][0]!=NULL) && (strcmp(vars[i][0], tempid) != 0)) {
		i++;
	}
	if (i>=256) {
		printf("REMEMBER: JOHN-JOHN DILLINGER DIED FOR YOUR SINS!\nIn memory of RAW\n");
		return 0;
	}
	if (vars[i][0]==NULL) {
		vars[i][0]=malloc(strlen(tempid)+1);
		snprintf(vars[i][0], strlen(tempid)+1, "%s", tempid);
		vars[i][1]=malloc(2);
		snprintf(vars[i][1], 2, "5");
	}
	int num=atoi(vars[i][1]);
	num-=hailcount;
	num/=discount;
	free(vars[i][1]);
	vars[i][1]=malloc(13);
	snprintf(vars[i][1], 13, "%i", num);
	free(tempid);
	}

"REMEMBER: SAINT "([A-Z\ ]*)" DIED FOR YOUR SINS!\n\n" {	
	printf("%s", yytext);
	return 0;
	}

"FORGET: SAINT "({NUMID}|{ID})" DIED FOR YOUR SINS!\n" {
	int i=0;
	int pos=(int)strstr(yytext, " DIED ")-((int)yytext);
	int start=strlen("FORGET: SAINT ");
	int len=pos-start;
	char* tempid=malloc(len);
	snprintf(tempid, len, "%s", (char*)(((int)yytext)+start-1));
	while(i<256 && strcmp(vars[i][0], tempid)!=0) {
		i++;
	}
	if (i<256) {
		free(vars[i][0]);
		free(vars[i][1]);
		vars[i][0]=NULL;
		vars[i][1]=NULL;
	}
	}


%%

main() {
	int i;
	for (i=0; i<256; i++) {
		vars[i][0]=NULL;
		vars[i][1]=NULL;
	}
	printf("DISCORDIA: THE LANGUAGE OF CHAOS\n(K) KOPYLEFT: ALL RIGHTS REVERSED\n\n");
	yylex();
	}

